Loading the required data…

cluster.assignments <- read.csv("Intermediate_results/regularity_of_study/regularity_based_clusters.csv")
exam.scores <- read.csv(file = "Intermediate_results/exam_scores_with_student_ids.csv")
# remove email data
exam.scores <- exam.scores %>% select(-2)
# merge exam scores and clusters
clust.and.scores <- merge(x = cluster.assignments %>% select(-cl3), 
                          y = exam.scores %>% select(-SC_MT_TOT),
                          by.x = "user_id", by.y = "USER_ID",
                          all.x = TRUE, all.y = FALSE)

Model 0: cluster assignment as the random effect, no fixed effects

Creating a baseline model with identified clusters as the random effect (no fixed effects)

Preparing the data for the model

lme_0_dat <- clust.and.scores %>% select(-user_id)
set.seed(seed)
lme_0 <- lmer(SC_FE_TOT ~ 1 + (1|cl4), data = lme_0_dat, REML = FALSE)
summary(lme_0)
Linear mixed model fit by maximum likelihood  ['lmerMod']
Formula: SC_FE_TOT ~ 1 + (1 | cl4)
   Data: lme_0_dat

     AIC      BIC   logLik deviance df.resid 
  3456.7   3469.2  -1725.4   3450.7      474 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.6319 -0.7970 -0.1212  0.6746  2.2443 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 22.90    4.785   
 Residual             78.81    8.878   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
            Estimate Std. Error t value
(Intercept)   18.159      2.434   7.461
## compute ICC
r.squaredGLMM(lme_0)
      R2m       R2c 
0.0000000 0.2251254 

22.51% of the total variance is explained by the cluster assignment

Checking if the model satisfies the assumptions for linear regression:

# assumption 1: the mean of residuals is zero
mean(resid(lme_0))
# OK
# assumption 2: homoscedasticity of residuals or equal variance
# assumption 3: Normality of residuals
check.residuals(lme_0)

check.residuals2(lme_0)

# OK

Model 1: Proportions and regularity of preparation (ontopic) sessions and last minute preparation sessions

Use as fixed effects:

prep.sessions <- read.csv("Intermediate_results/regularity_of_study/on_topic_and_last_min_proportions.csv")
# str(prep.sessions)
lme_1_dat <- merge(x = prep.sessions %>% select(-ends_with("mad")), 
                   y = clust.and.scores, 
                   by = "user_id", all.x = F, all.y = T)
summary(lme_1_dat)
plot.correlations(lme_1_dat)

lme_1_dat <- lme_1_dat %>% select(-user_id)
set.seed(seed)
lme_1 <- lmer(SC_FE_TOT ~ on_topic_prop + on_topic_prop_sd + last_min_prop + last_min_prop_sd +
                (1|cl4), data = lme_1_dat, REML = FALSE)
summary(lme_1)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ on_topic_prop + on_topic_prop_sd + last_min_prop +  
    last_min_prop_sd + (1 | cl4)
   Data: lme_1_dat

     AIC      BIC   logLik deviance df.resid 
  3354.2   3383.2  -1670.1   3340.2      458 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.71757 -0.75786 -0.08334  0.77814  2.26202 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 13.66    3.696   
 Residual             75.15    8.669   
Number of obs: 465, groups:  cl4, 4

Fixed effects:
                 Estimate Std. Error      df t value Pr(>|t|)    
(Intercept)        21.162      3.595  43.700   5.886 5.09e-07 ***
on_topic_prop       4.039      3.368 462.300   1.199   0.2310    
on_topic_prop_sd  -11.682      5.557 465.000  -2.102   0.0361 *  
last_min_prop       2.265      5.129 461.200   0.442   0.6590    
last_min_prop_sd   -4.107      3.153 461.500  -1.302   0.1934    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) on_tp_ on_t__ lst_m_
on_topc_prp -0.721                     
on_tpc_prp_ -0.730  0.588              
last_mn_prp  0.070 -0.314  0.050       
lst_mn_prp_ -0.306  0.276  0.016 -0.519

Only on_topic_prop_sd is significant; a unit increase, leads to a decrease of the final exam score

Compare the model with the baseline

# lme_1_base <- lmer(SC_FE_TOT ~ 1 + (1|cl4), data = lme_1_dat, REML = FALSE)
# anova(lme_1, lme_1_base)

Cannot be compared as they do not have the same number of observations: some observations were removed from the lme_1 model due to NA values

## compute ICC
r.squaredGLMM(lme_1)
       R2m        R2c 
0.03849303 0.18641196 

The overall model explains 18.64% of variability in the final exam score; only a small portion - 3.85% - of this variability is explained by the fixed factors

Checking if model assumptions hold

# if residuals are normally distributed with constant standard deviation
check.residuals(lme_1)

# check for multicolinearity
max(vif.mer(lme_1))

Assumptions do hold

Model 2: Number of study sessions per week day, and week day entropy of study session counts as fixed effects

Loading the data

weekday.sessions <- read.csv("Intermediate_results/regularity_of_study/weekday_session_props.csv")
# str(weekday.sessions)
lme_2_dat <- merge(x = weekday.sessions %>% select(1:8, 11),
                  y = clust.and.scores,
                  by = "user_id", all.x = FALSE, all.y = TRUE)
lme_2_dat <- lme_2_dat %>% select(-user_id)
#summary(lme_2_dat)
# since the count variables are on a very different scale than the entropy, standardize them
lme_2_st_dat <- scale.features(lme_2_dat)
#summary(lme_2_st_dat)
set.seed(seed)
lme_2 <- lmer(SC_FE_TOT ~ Sun_count + Mon_count + Tue_count + Wed_count + Thu_count + Fri_count +
                Sat_count + weekday_entropy + (1|cl4), data = lme_2_st_dat, REML = FALSE)
summary(lme_2)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ Sun_count + Mon_count + Tue_count + Wed_count + Thu_count +  
    Fri_count + Sat_count + weekday_entropy + (1 | cl4)
   Data: lme_2_st_dat

     AIC      BIC   logLik deviance df.resid 
   842.8    888.7   -410.4    820.8      466 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.6402 -0.7160 -0.1153  0.7892  2.3632 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 0.0000   0.000   
 Residual             0.3272   0.572   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
                  Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)       0.007812   0.032484 477.000000   0.240  0.81005    
Sun_count         0.039472   0.045232 477.000000   0.873  0.38329    
Mon_count         0.176776   0.041865 477.000000   4.222 2.89e-05 ***
Tue_count         0.132384   0.041767 477.000000   3.170  0.00162 ** 
Wed_count         0.100672   0.041470 477.000000   2.428  0.01557 *  
Thu_count         0.139886   0.035479 477.000000   3.943 9.26e-05 ***
Fri_count         0.048541   0.040518 477.000000   1.198  0.23151    
Sat_count        -0.006031   0.033196 477.000000  -0.182  0.85592    
weekday_entropy   0.083886   0.032368 477.000000   2.592  0.00985 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Sn_cnt Mn_cnt Tu_cnt Wd_cnt Th_cnt Fr_cnt St_cnt
Sun_count   -0.246                                                 
Mon_count   -0.226 -0.335                                          
Tue_count   -0.073  0.005  0.000                                   
Wed_count   -0.254 -0.048  0.274 -0.045                            
Thu_count   -0.013 -0.140  0.018 -0.024 -0.226                     
Fri_count    0.012 -0.002 -0.129 -0.104 -0.030 -0.274              
Sat_count   -0.109 -0.319  0.025 -0.127 -0.138  0.036 -0.232       
wekdy_ntrpy  0.432 -0.228 -0.134 -0.038 -0.117 -0.013 -0.143 -0.204

As in regular linear model (Model 5), Mon, Tue, Wed, and Thu session counts are significant, as is the weekday entropy.

Compare the model with the baseline

lme_2_base <- lmer(SC_FE_TOT ~ 1 + (1|cl4), data = lme_2_st_dat, REML = FALSE)
anova(lme_2, lme_2_base)
Data: lme_2_st_dat
Models:
..1: SC_FE_TOT ~ 1 + (1 | cl4)
object: SC_FE_TOT ~ Sun_count + Mon_count + Tue_count + Wed_count + Thu_count + 
object:     Fri_count + Sat_count + weekday_entropy + (1 | cl4)
       Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)    
..1     3 873.25 885.75 -433.62   867.25                             
object 11 842.82 888.66 -410.41   820.82 46.428      8  1.971e-07 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Model 2 is significantly better than the baseline.

## compute ICC
r.squaredGLMM(lme_2)
     R2m      R2c 
0.231116 0.231116 

Since marginal R2 and conditional R2 are exactly the same, it means that all the variability is explained by the fixed factors; the random factor does not contribute (also visible in the model summary).

Checking if residuals are normally distributed with constant standard deviation

check.residuals(lme_2)

check.residuals2(lme_2)

Not fully fine, but also not too bad

Check for multicolinearity

max(vif.mer(lme_2))
[1] 1.755446

It’s OK

Model 3: Daily resource use (as fixed effects)

Loading the data…

res.use.stats <- read.csv("Intermediate_results/regularity_of_study/daily_resource_use_statistics_w2-5_7-12.csv")
lme_3_dat <- merge(res.use.stats, clust.and.scores, by = "user_id", all.x = F, all.y = T)
lme_3_dat <- lme_3_dat %>% select(-user_id)

Use total daily resource counts as fixed effects

lme_3.1_dat <- lme_3_dat %>% select(starts_with("tot"), cl4, SC_FE_TOT)
plot.correlations(lme_3.1_dat)

set.seed(seed)
lme_3.1 <- lmer(SC_FE_TOT ~ tot_video_cnt + tot_exe_cnt + tot_mcq_cnt + tot_mcog_cnt + 
                  tot_res_cnt + (1|cl4), data = lme_3.1_dat, REML = FALSE)
summary(lme_3.1)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ tot_video_cnt + tot_exe_cnt + tot_mcq_cnt + tot_mcog_cnt +  
    tot_res_cnt + (1 | cl4)
   Data: lme_3.1_dat

     AIC      BIC   logLik deviance df.resid 
  3419.2   3452.6  -1701.6   3403.2      469 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.82298 -0.77938 -0.01984  0.75193  2.82197 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 19.45    4.410   
 Residual             71.38    8.449   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
                Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)    2.198e+01  2.521e+00  5.900e+00   8.718 0.000141 ***
tot_video_cnt  3.904e-04  8.399e-04  4.751e+02   0.465 0.642307    
tot_exe_cnt   -7.283e-03  1.131e-03  4.743e+02  -6.438 2.96e-10 ***
tot_mcq_cnt    5.216e-03  3.407e-03  4.736e+02   1.531 0.126447    
tot_mcog_cnt   6.081e-03  1.225e-02  4.729e+02   0.496 0.619819    
tot_res_cnt    5.105e-03  1.924e-03  4.767e+02   2.654 0.008216 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) tt_vd_ tt_x_c tt_mcq_ tt_mcg_
tot_vid_cnt -0.035                              
tot_exe_cnt -0.350 -0.051                       
tot_mcq_cnt  0.025 -0.193 -0.065                
tot_mcg_cnt -0.044 -0.019  0.056 -0.211         
tot_res_cnt -0.142 -0.085 -0.225 -0.372  -0.187 

Predictors with siginifican effect:

  • total number of exercise-related events - each new event of this type decreases the exam score by 0.0073 points
  • total number of reading-related events - each new event of this type increases the exam score by 0.0051 points

Compare the model with the baseline

lme_3.1_base <- lmer(SC_FE_TOT ~ 1 + (1|cl4), data = lme_3.1_dat, REML = FALSE)
anova(lme_3.1, lme_3.1_base)
Data: lme_3.1_dat
Models:
..1: SC_FE_TOT ~ 1 + (1 | cl4)
object: SC_FE_TOT ~ tot_video_cnt + tot_exe_cnt + tot_mcq_cnt + tot_mcog_cnt + 
object:     tot_res_cnt + (1 | cl4)
       Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)    
..1     3 3456.7 3469.2 -1725.4   3450.7                             
object  8 3419.2 3452.6 -1701.6   3403.2 47.501      5   4.49e-09 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

The new model (lme_3.1) is significantly better than the baseline.

r.squaredGLMM(lme_3.1)
       R2m        R2c 
0.08230082 0.27882260 

The overall model explains 27.88% of variability in the final exam score; fixed effects explain only 8.23%

Checking if model assumptions are satisfied

# if residuals are normally distributed and if equality of variance holds
check.residuals(lme_3.1)

check.residuals2(lme_3.1)

# check for multicolinearity
max(vif.mer(lme_3.1))

It is questionable if the equality of variance assumption holds; other things are fine.

Add regularity indicators - MAD of daily resource counts (to fixed effects)

lme_3.2_dat <- lme_3_dat %>% select(starts_with("tot"), starts_with("mad"), cl4, SC_FE_TOT)
plot.correlations(lme_3.2_dat)

# remove mad_rec_cnt as highly correlated with tot_res_cnt
lme_3.2_dat <- lme_3.2_dat %>% select(-mad_res_cnt)
# summary(lme_3.2_dat)
# some variables have very different scales - need to be rescaled 
lme_3.2_st_dat <- scale.features(lme_3.2_dat %>% select(-c(cl4, SC_FE_TOT)))
# summary(lme_3.2_st_dat)
# when rescalled, almost all regularity indicators (MAD) values become zero

Not applicable, as when rescalled, MAD values become zero; this is due to their highly unregular distribution with numerous outliers

Model 4: Daily topic focus (as fixed effects)

Loading the data…

topic.stats <- read.csv("Intermediate_results/regularity_of_study/topic_counts_statistics_w2-5_7-12.csv")
lme_4_dat <- merge(topic.stats, clust.and.scores, by = "user_id", all.x = F, all.y = T)
lme_4_dat <- lme_4_dat %>% select(-user_id)

Use the proportion of days with each topic focus as the fixed effects

Note: initially, I wanted to use days (with each topic focus), but X_days variables are highly mutually correlated

lme_4.1_dat <- lme_4_dat %>% select(ends_with("prop"), cl4, SC_FE_TOT)
plot.correlations(lme_4.1_dat)

# remove orient_prop as highly correlated with metacog_prop; also prj_prop as having zero correlation with the exam score
lme_4.1_dat <- lme_4.1_dat %>% select(-c(prj_prop, orient_prop))
set.seed(seed)
lme_4.1 <- lmer(SC_FE_TOT ~ ontopic_prop + revisit_prop + metacog_prop + (1|cl4), 
                data = lme_4.1_dat, REML = FALSE)
summary(lme_4.1)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ ontopic_prop + revisit_prop + metacog_prop + (1 |      cl4)
   Data: lme_4.1_dat

     AIC      BIC   logLik deviance df.resid 
  3451.1   3476.1  -1719.6   3439.1      471 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.36012 -0.74169 -0.08928  0.78733  2.30709 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 20.62    4.541   
 Residual             76.97    8.773   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
             Estimate Std. Error       df t value Pr(>|t|)   
(Intercept)   31.5711    10.2162 384.2000   3.090  0.00215 **
ontopic_prop   7.4762     2.9122 473.2000   2.567  0.01056 * 
revisit_prop  -0.8163     2.6449 473.1000  -0.309  0.75772   
metacog_prop -17.5504     9.8078 474.1000  -1.789  0.07418 . 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) ontpc_ rvst_p
ontopic_prp -0.257              
revisit_prp -0.226  0.325       
metacog_prp -0.951  0.077  0.077

The only significant fixed effect is ontopic_prop - the proportion of active days when a student was preparing for the week’s lecture

r.squaredGLMM(lme_4.1)
       R2m        R2c 
0.01990326 0.22697643 

The overall model explains 22.7% of variance in the final exam score; fixed effects contribute only 2% of explained variance

Compare the model with the baseline

lme_4.1_base <- lmer(SC_FE_TOT ~ 1 + (1|cl4), data = lme_4.1_dat, REML = FALSE)
anova(lme_4.1, lme_4.1_base)
Data: lme_4.1_dat
Models:
..1: SC_FE_TOT ~ 1 + (1 | cl4)
object: SC_FE_TOT ~ ontopic_prop + revisit_prop + metacog_prop + (1 | 
object:     cl4)
       Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)   
..1     3 3456.7 3469.2 -1725.4   3450.7                            
object  6 3451.1 3476.1 -1719.6   3439.1 11.617      3   0.008816 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

The new model (lme_4.1) is significantly better than the baseline.

Use the total number of actions per day with particular topic focus as the fixed effects

lme_4.2_dat <- lme_4_dat %>% select(starts_with("tot"), cl4, SC_FE_TOT)
plot.correlations(lme_4.2_dat)

# remove tot_metacog_cnt as highly correlated with several other variables; also, tot_revisit_cnt has zero correlation with the final exam score
lme_4.2_dat <- lme_4.2_dat %>% select(-c(tot_metacog_cnt, tot_revisit_cnt))
set.seed(seed)
lme_4.2 <- lmer(SC_FE_TOT ~ tot_ontopic_cnt + tot_orient_cnt + tot_prj_cnt + (1|cl4), 
                data = lme_4.2_dat, REML = FALSE)
summary(lme_4.2)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ tot_ontopic_cnt + tot_orient_cnt + tot_prj_cnt +      (1 | cl4)
   Data: lme_4.2_dat

     AIC      BIC   logLik deviance df.resid 
  3453.0   3478.0  -1720.5   3441.0      471 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.49365 -0.79573 -0.07265  0.72290  2.30886 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 14.59    3.820   
 Residual             77.50    8.803   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
                  Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)      1.610e+01  2.141e+00  5.100e+00   7.517 0.000598 ***
tot_ontopic_cnt  1.846e-03  9.409e-04  4.769e+02   1.962 0.050356 .  
tot_orient_cnt   7.955e-03  4.402e-03  4.769e+02   1.807 0.071400 .  
tot_prj_cnt     -2.110e-02  1.457e-02  4.728e+02  -1.448 0.148255    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) tt_nt_ tt_rn_
tt_ntpc_cnt -0.196              
tot_rnt_cnt -0.167 -0.303       
tot_prj_cnt -0.065  0.087 -0.633
r.squaredGLMM(lme_4.2)
       R2m        R2c 
0.02603713 0.18035337 

Very poor model…

Cosider using indicators of regularity of topic focus as the fixed effects

lme_4.3_dat <- lme_4_dat %>% select(starts_with("mad"), cl4, SC_FE_TOT)
plot.correlations(lme_4.3_dat)

Better not to, since the mad_X_cnt variables have very low correlation with the final exam score - significant fixed effect cannot be expected.

Model 5: Weekly resource use indicators as fixed effects

Indicators are computed at the week level, based on the following principle: a score of one is given to a student (for a given week), if he/she used certain kind of resource (e.g. video) more than the average (median) use of the that resource type in the given week

Loading the data

res.use.ind <- read.csv("Intermediate_results/regularity_of_study/res_use_indicators_w2-13.csv")
str(res.use.ind)
lme_5_dat <- merge(x = res.use.ind, y = clust.and.scores,
                  by = "user_id", all.x = FALSE, all.y = TRUE)
lme_5_dat <- lme_5_dat %>% select(-user_id)
summary(lme_5_dat)
plot.correlations(lme_5_dat)

# res_ind and MCQ_ind are highly correlated, remove one of them
lme_5_dat <- lme_5_dat %>% select(-VIDEO_ind)
set.seed(seed)
lme_5 <- lmer(SC_FE_TOT ~ MCQ_ind + EXE_ind + RES_ind + METACOG_ind + (1|cl4), 
                data = lme_5_dat, REML = FALSE)
summary(lme_5)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ MCQ_ind + EXE_ind + RES_ind + METACOG_ind + (1 |      cl4)
   Data: lme_5_dat

     AIC      BIC   logLik deviance df.resid 
  3376.0   3405.2  -1681.0   3362.0      470 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-3.07989 -0.71301 -0.01201  0.76355  2.59049 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 10.12    3.181   
 Residual             65.78    8.110   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
            Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)  18.6868     1.9966   7.0000   9.360 3.28e-05 ***
MCQ_ind       0.7786     0.1651 477.0000   4.715 3.18e-06 ***
EXE_ind      -0.9767     0.1415 476.7000  -6.902 1.65e-11 ***
RES_ind       0.3550     0.1575 466.7000   2.254   0.0247 *  
METACOG_ind  -0.0258     0.1527 473.2000  -0.169   0.8659    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) MCQ_nd EXE_nd RES_nd
MCQ_ind     -0.124                     
EXE_ind     -0.384  0.089              
RES_ind     -0.220 -0.387 -0.142       
METACOG_ind -0.130 -0.389  0.031 -0.016

Predictors with significant effect:

Compare the model with the baseline

lme_5_base <- lmer(SC_FE_TOT ~ 1 + (1|cl4), data = lme_5_dat, REML = FALSE)
anova(lme_5, lme_5_base)
Data: lme_5_dat
Models:
..1: SC_FE_TOT ~ 1 + (1 | cl4)
object: SC_FE_TOT ~ MCQ_ind + EXE_ind + RES_ind + METACOG_ind + (1 | 
object:     cl4)
       Df    AIC    BIC  logLik deviance Chisq Chi Df Pr(>Chisq)    
..1     3 3456.7 3469.2 -1725.4   3450.7                            
object  7 3376.0 3405.2 -1681.0   3362.0 88.69      4  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

The model is significantly better than the baseline.

r.squaredGLMM(lme_5)
      R2m       R2c 
0.1835686 0.2924003 

The best model so far: it explains 29.24% of the variability in the final exam score; out of that, 18.35% are explained by the fixed factors.

Checking if model assumptions are satisfied

# if residuals are normally distributed and if equality of variance holds
check.residuals(lme_5)

check.residuals2(lme_5)

# check for multicolinearity
max(vif.mer(lme_5))

It can be said that the assumptions hold

Model 6: Topic focus indicators as fixed effects

Indicators are computed at the week level, based on the following principle: a score of one is given to a student (for a given week), if his/her number of events related to a particular topic type (e.g. revisiting) was above the average (median) number of events with that topic type in the given week

Weeks 6 and 13 are excluded from these computations, as during these weeks one can expect different behavioral patterns than usual.

Loading the data

topic.ind <- read.csv("Intermediate_results/regularity_of_study/topic_based_indicators_w2-5_7-12.csv")
str(topic.ind)
lme_6_dat <- merge(x = topic.ind, y = clust.and.scores,
                  by = "user_id", all.x = FALSE, all.y = TRUE)
lme_6_dat <- lme_6_dat %>% select(-user_id)
summary(lme_6_dat)
plot.correlations(lme_6_dat)

# orient_ind and metacog_ind are highly correlated, remove one of them
lme_6_dat <- lme_6_dat %>% select(-orient_ind)
set.seed(seed)
lme_6 <- lmer(SC_FE_TOT ~ ontopic_ind + revisit_ind + metacog_ind + prj_ind + (1|cl4), 
                data = lme_6_dat, REML = FALSE)
summary(lme_6)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ ontopic_ind + revisit_ind + metacog_ind + prj_ind +      (1 | cl4)
   Data: lme_6_dat

     AIC      BIC   logLik deviance df.resid 
  3446.8   3476.0  -1716.4   3432.8      470 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.43718 -0.77507 -0.05424  0.76676  2.52504 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 14.40    3.795   
 Residual             76.17    8.728   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
             Estimate Std. Error        df t value Pr(>|t|)    
(Intercept)  16.92282    2.26804   6.20000   7.461 0.000255 ***
ontopic_ind   0.51851    0.17969 470.10000   2.886 0.004087 ** 
revisit_ind  -0.44263    0.16810 475.60000  -2.633 0.008735 ** 
metacog_ind   0.19592    0.20887 476.70000   0.938 0.348728    
prj_ind       0.03693    0.30348 474.30000   0.122 0.903203    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) ontpc_ rvst_n mtcg_n
ontopic_ind -0.284                     
revisit_ind -0.260  0.109              
metacog_ind -0.044 -0.269 -0.304       
prj_ind     -0.171  0.013  0.035 -0.473

Significant fixed effects:

Compare the model with the baseline

lme_6_base <- lmer(SC_FE_TOT ~ 1 + (1|cl4), data = lme_6_dat, REML = FALSE)
anova(lme_6, lme_6_base)
Data: lme_6_dat
Models:
..1: SC_FE_TOT ~ 1 + (1 | cl4)
object: SC_FE_TOT ~ ontopic_ind + revisit_ind + metacog_ind + prj_ind + 
object:     (1 | cl4)
       Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)   
..1     3 3456.7 3469.2 -1725.4   3450.7                            
object  7 3446.8 3476.0 -1716.4   3432.8 17.912      4   0.001284 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

The model is significantly better than the baseline.

r.squaredGLMM(lme_6)
       R2m        R2c 
0.04183826 0.19421923 

The model explains 19.42% of the variability in the final exam score; out of that, 4.18% are explained by the fixed factors.

Checking if model assumptions are satisfied

# if residuals are normally distributed and if equality of variance holds
check.residuals(lme_6)

#check.residuals2(lme_6)
# check for multicolinearity
max(vif.mer(lme_6))

It’s fine - the assumptions hold.

Model 7: Time gap (in days) between two consecutive active days (as fixed effect)

Loading the data

reg.ind <- read.csv("Intermediate_results/regularity_of_study/gaps_between_consecutive_logins_w2-13.csv")
str(reg.ind)
lme_7_dat <- merge(x = reg.ind %>% select(user_id, median_gap), y = clust.and.scores,
                  by = "user_id", all.x = FALSE, all.y = TRUE)
lme_7_dat <- lme_7_dat %>% select(-user_id)
summary(lme_7_dat)
plot.correlations(lme_7_dat)

set.seed(seed)
lme_7 <- lmer(SC_FE_TOT ~ median_gap + (1|cl4), 
                data = lme_7_dat, REML = FALSE)
summary(lme_7)
Linear mixed model fit by maximum likelihood t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: SC_FE_TOT ~ median_gap + (1 | cl4)
   Data: lme_7_dat

     AIC      BIC   logLik deviance df.resid 
  3452.3   3469.0  -1722.2   3444.3      473 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.6382 -0.7942 -0.1186  0.6717  2.2550 

Random effects:
 Groups   Name        Variance Std.Dev.
 cl4      (Intercept) 11.61    3.408   
 Residual             78.18    8.842   
Number of obs: 477, groups:  cl4, 4

Fixed effects:
            Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)  19.4150     1.8147   3.6700  10.698 0.000671 ***
median_gap   -1.0121     0.3716 270.8400  -2.724 0.006879 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
           (Intr)
median_gap -0.243

Median gap, measured in days, is significant: one unit (day) increase in this predictor leads to a 1.01 decrase in the student’s final exam score.

r.squaredGLMM(lme_7)
       R2m        R2c 
0.02499718 0.15107312 

The model explains 15.11% of the variability in the final exam score; out of that, only 2.5% are explained by the fixed factors.

Checking if model assumptions are satisfied

# if residuals are normally distributed and if equality of variance holds
check.residuals(lme_7)

#check.residuals2(lme_6)
# check for multicolinearity
max(vif.mer(lme_7))

It’s fine - the assumptions hold.

LS0tCnRpdGxlOiAiVXNpbmcgbWl4LWVmZmVjdCBtb2RlbHMgdG8gZXhhbWluZSByZWd1bGFyaXR5IG9mIHN0dWR5IGFuZCBpdHMgZWZmZWN0IG9uIHN0dWRlbnQgZXhhbSBwZXJmb3JtYW5jZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKCiMgbG9hZCB0aGUgcmVxdWlyZWQgbGlicmFyaWVzIGFuZCBmdW5jdGlvbnMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoa25pdHIpCgpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkobG1lclRlc3QpCmxpYnJhcnkoTXVNSW4pCgpzb3VyY2UoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9icmlhdHRlL2dnY29yci9tYXN0ZXIvZ2djb3JyLlIiKQoKc2VlZCA8LSAyNTcyMDE3CmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KCnBsb3QuY29ycmVsYXRpb25zIDwtIGZ1bmN0aW9uKGRhdGFzZXQpIHsKICBnZ2NvcnIoZGF0YXNldCwgbWV0aG9kID0gYygiY29tcGxldGUiLCJzcGVhcm1hbiIpLCAKICAgICAgICMgICAgICBnZW9tID0gImNpcmNsZSIsIG1pbl9zaXplID0gMCwgbWF4X3NpemUgPSAxNSwKICAgICAgIGxhYmVsID0gVFJVRSwgbGFiZWxfc2l6ZSA9IDMuNSwKICAgICAgIGhqdXN0ID0gMC44NSwgc2l6ZSA9IDQsIGxheW91dC5leHAgPSAxKQp9CgoKIyMgdGhlIGYuIHNjYWxlcyB0aGUgZ2l2ZW4gZmVhdHVyZSBzZXQgYnkgc3RhbmRhcmRpemluZyB0aGVtCiMjIGFzIGZlYXR1cmVzIGFyZSBleHBlY3RlZCB0byBoYXZlIG91dGxpZXJzLCBpbnN0ZWFkIG9mIHVzaW5nIG1lYW4gYW5kIFNELCAKIyMgbWVkaWFuIGFuZCBJbnRlcnF1YXJ0aWxlIFJhbmdlIChJUVIpIGFyZSB1c2VkLCBhcyBzdWdnZXN0ZWQgaGVyZToKIyMgaHR0cDovL3NjaWtpdC1sZWFybi5vcmcvc3RhYmxlL21vZHVsZXMvcHJlcHJvY2Vzc2luZy5odG1sI3NjYWxpbmctZGF0YS13aXRoLW91dGxpZXJzCnNjYWxlLmZlYXR1cmVzIDwtIGZ1bmN0aW9uKGZlYXR1cmVzKSB7CiAgbSA8LSBtYXRyaXgobnJvdyA9IG5yb3coZmVhdHVyZXMpLCBuY29sID0gbmNvbChmZWF0dXJlcyksIGJ5cm93ID0gRkFMU0UpCiAgaSA8LSAxCiAgZm9yKGYgaW4gZmVhdHVyZXMpIHsKICAgIGlmICggSVFSKHggPSBmLCBuYS5ybSA9IFQpICE9IDAgKQogICAgICBtWyxpXSA8LSAoZiAtIG1lZGlhbihmLCBuYS5ybSA9IFQpKS9JUVIoZiwgbmEucm0gPSBUKQogICAgZWxzZQogICAgICBtWyxpXSA8LSAwCiAgICBpIDwtIGkgKyAxICAKICB9CiAgc2NhbGVkLmRhdGEgPC0gZGF0YS5mcmFtZShtKQogIGNvbG5hbWVzKHNjYWxlZC5kYXRhKSA8LSBjb2xuYW1lcyhmZWF0dXJlcykKICAjIHNjYWxlZC5kYXRhIDwtIGRhdGEuZnJhbWUoYXBwbHkoZmVhdHVyZXMsIDIsIAogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7KHgtbWVkaWFuKHgsIG5hLnJtID0gVCkpL0lRUih4LCBuYS5ybSA9IFQpfSApKQogIHNjYWxlZC5kYXRhCn0KCgojIyBmLiBkcmF3cyAyIHBsb3RzOiAxKSBmb3IgY2hlY2tpbmcgaWYgcmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZCAKIyMgMikgZm9yIGNoZWNraW5nIHRoZSBob21vc2tlZGFzdGljaXR5IGFzc3VtcHRpb24KY2hlY2sucmVzaWR1YWxzIDwtIGZ1bmN0aW9uKGxtZS5tb2QpIHsKICBwYXIobWZyb3cgPSBjKDIsMSkpCiAgCiAgIyMgZmlyc3QsIGNoZWNrIGZvciB0aGUgbm9ybWFsaXR5IG9mIHJlc2lkdWFscyBhc3N1bXB0aW9uCiAgcXFub3JtKHJlc2lkKGxtZS5tb2QpKSAKICBxcWxpbmUocmVzaWQobG1lLm1vZCkpCiAgCiAgIyMgbm93LCBkcmF3IGEgcGxvdCB0byBjaGVjayBpZiB0aGUgcmVzaWR1YWxzIGhhdmUgCiAgIyMgYXBwcm94aW1hdGVseSBlcXVhbCBkZXZpYXRpb24gZnJvbSB0aGUgcHJlZGljdGVkIHZhbHVlcwogIHBsb3QoZml0dGVkKGxtZS5tb2QpLAogICAgICAgcmVzaWQobG1lLm1vZCx0eXBlPSJwZWFyc29uIiksCiAgICAgICBjb2w9ImJsdWUiKSAKICBhYmxpbmUoaD0wLGx3ZD0yKQogIGxpbmVzKHNtb290aC5zcGxpbmUoZml0dGVkKGxtZS5tb2QpLCByZXNpZHVhbHMobG1lLm1vZCkpLCBsd2Q9MiwgY29sPSdyZWQnKQogIAogIHBhcihtZnJvdyA9IGMoMSwxKSkKfQoKIyMgYW5vdGhlciB3YXkgb2YgdXNpbmcgcmVzaWR1YWwgcGxvdCB0byBleGFtaW5lIHRoZSBmaXR0bmVzIG9mIHRoZSBidWlsdCBtb2RlbAojIyBmcm9tOiBodHRwOi8vZ29vLmdsLzBhdm9pdApjaGVjay5yZXNpZHVhbHMyIDwtIGZ1bmN0aW9uKGxtZS5tb2QpIHsKICBwbG90KGZpdHRlZChsbWUubW9kKSwgCiAgICAgICByZXNpZHVhbHMobG1lLm1vZCksIAogICAgICAgeGxhYiA9ICJGaXR0ZWQgVmFsdWVzIiwgeWxhYiA9ICJSZXNpZHVhbHMiLCBjb2w9J2JsdWUnKQogIGFibGluZShoID0gMCwgbHR5ID0gMikKICBsaW5lcyhzbW9vdGguc3BsaW5lKGZpdHRlZChsbWUubW9kKSwgCiAgICAgICAgICAgICAgICAgICAgICByZXNpZHVhbHMobG1lLm1vZCkpLCBsd2Q9MikKfQoKIyMgZi4gZm9yIGNvbXB1dGluZyBWSUYgKFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3IpLCB1c2VkIGZvciBjaGVja2luZwojIyBtdWx0aWNvbGluZWFyaXR5CiMjIHRha2VuIGZyb206IGh0dHBzOi8vZ2l0aHViLmNvbS9hdWZyYW5rL1ItaGFja3MvYmxvYi9tYXN0ZXIvbWVyLXV0aWxzLlIKdmlmLm1lciA8LSBmdW5jdGlvbiAoZml0KSB7CiAgIyMgYWRhcHRlZCBmcm9tIHJtczo6dmlmCiAgCiAgdiA8LSB2Y292KGZpdCkKICBuYW0gPC0gbmFtZXMoZml4ZWYoZml0KSkKICAKICAjIyBleGNsdWRlIGludGVyY2VwdHMKICBucyA8LSBzdW0oMSAqIChuYW0gPT0gIkludGVyY2VwdCIgfCBuYW0gPT0gIihJbnRlcmNlcHQpIikpCiAgaWYgKG5zID4gMCkgewogICAgdiA8LSB2Wy0oMTpucyksIC0oMTpucyksIGRyb3AgPSBGQUxTRV0KICAgIG5hbSA8LSBuYW1bLSgxOm5zKV0KICB9CiAgCiAgZCA8LSBkaWFnKHYpXjAuNQogIHYgPC0gZGlhZyhzb2x2ZSh2LyhkICVvJSBkKSkpCiAgbmFtZXModikgPC0gbmFtCiAgdgp9CmBgYAoKCkxvYWRpbmcgdGhlIHJlcXVpcmVkIGRhdGEuLi4KYGBge3J9CmNsdXN0ZXIuYXNzaWdubWVudHMgPC0gcmVhZC5jc3YoIkludGVybWVkaWF0ZV9yZXN1bHRzL3JlZ3VsYXJpdHlfb2Zfc3R1ZHkvcmVndWxhcml0eV9iYXNlZF9jbHVzdGVycy5jc3YiKQoKZXhhbS5zY29yZXMgPC0gcmVhZC5jc3YoZmlsZSA9ICJJbnRlcm1lZGlhdGVfcmVzdWx0cy9leGFtX3Njb3Jlc193aXRoX3N0dWRlbnRfaWRzLmNzdiIpCiMgcmVtb3ZlIGVtYWlsIGRhdGEKZXhhbS5zY29yZXMgPC0gZXhhbS5zY29yZXMgJT4lIHNlbGVjdCgtMikKCiMgbWVyZ2UgZXhhbSBzY29yZXMgYW5kIGNsdXN0ZXJzCmNsdXN0LmFuZC5zY29yZXMgPC0gbWVyZ2UoeCA9IGNsdXN0ZXIuYXNzaWdubWVudHMgJT4lIHNlbGVjdCgtY2wzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGV4YW0uc2NvcmVzICU+JSBzZWxlY3QoLVNDX01UX1RPVCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnkueCA9ICJ1c2VyX2lkIiwgYnkueSA9ICJVU0VSX0lEIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBhbGwueCA9IFRSVUUsIGFsbC55ID0gRkFMU0UpCmBgYAoKCiMjIyBNb2RlbCAwOiBjbHVzdGVyIGFzc2lnbm1lbnQgYXMgdGhlIHJhbmRvbSBlZmZlY3QsIG5vIGZpeGVkIGVmZmVjdHMKCkNyZWF0aW5nIGEgYmFzZWxpbmUgbW9kZWwgd2l0aCBpZGVudGlmaWVkIGNsdXN0ZXJzIGFzIHRoZSByYW5kb20gZWZmZWN0IChubyBmaXhlZCBlZmZlY3RzKQoKUHJlcGFyaW5nIHRoZSBkYXRhIGZvciB0aGUgbW9kZWwKYGBge3J9CmxtZV8wX2RhdCA8LSBjbHVzdC5hbmQuc2NvcmVzICU+JSBzZWxlY3QoLXVzZXJfaWQpCmBgYAoKYGBge3J9CnNldC5zZWVkKHNlZWQpCmxtZV8wIDwtIGxtZXIoU0NfRkVfVE9UIH4gMSArICgxfGNsNCksIGRhdGEgPSBsbWVfMF9kYXQsIFJFTUwgPSBGQUxTRSkKc3VtbWFyeShsbWVfMCkKYGBgCgpgYGB7cn0KIyMgY29tcHV0ZSBJQ0MKci5zcXVhcmVkR0xNTShsbWVfMCkKYGBgCjIyLjUxJSBvZiB0aGUgdG90YWwgdmFyaWFuY2UgaXMgZXhwbGFpbmVkIGJ5IHRoZSBjbHVzdGVyIGFzc2lnbm1lbnQKCkNoZWNraW5nIGlmIHRoZSBtb2RlbCBzYXRpc2ZpZXMgdGhlIGFzc3VtcHRpb25zIGZvciBsaW5lYXIgcmVncmVzc2lvbjoKYGBge3IgcmVzdWx0cz0naGlkZSd9CiMgYXNzdW1wdGlvbiAxOiB0aGUgbWVhbiBvZiByZXNpZHVhbHMgaXMgemVybwptZWFuKHJlc2lkKGxtZV8wKSkKIyBPSwoKIyBhc3N1bXB0aW9uIDI6IGhvbW9zY2VkYXN0aWNpdHkgb2YgcmVzaWR1YWxzIG9yIGVxdWFsIHZhcmlhbmNlCiMgYXNzdW1wdGlvbiAzOiBOb3JtYWxpdHkgb2YgcmVzaWR1YWxzCmNoZWNrLnJlc2lkdWFscyhsbWVfMCkKY2hlY2sucmVzaWR1YWxzMihsbWVfMCkKIyBPSwpgYGAKCgojIyMgTW9kZWwgMTogUHJvcG9ydGlvbnMgYW5kIHJlZ3VsYXJpdHkgb2YgcHJlcGFyYXRpb24gKG9udG9waWMpIHNlc3Npb25zIGFuZCBsYXN0IG1pbnV0ZSBwcmVwYXJhdGlvbiBzZXNzaW9ucwoKVXNlIGFzIGZpeGVkIGVmZmVjdHM6CgoqIHByb3BvcnRpb25zIG9mICdwcmVwYXJhdGlvbicgc2Vzc2lvbnMsIHRoYXQgaXMsIHNlc3Npb25zIHdpdGggdGhlIG1haW5fdG9waWMgYmVpbmcgdGhlIHRvcGljIG9mIHRoZSB3ZWVrJ3MgbGVjdHVyZQoqIHByb3BvcnRpb25zIG9mICdsYXN0IG1pbnV0ZSBwcmVwYXJhdGlvbiBzZXNzaW9ucycsIHRoYXQgaXMsICdwcmVwYXJhdGlvbicgc2Vzc2lvbnMgZG9uZSBpbiAyNGggYmVmb3JlIGEgd2VlaydzIGxlY3R1cmU7CiogIFNEIG9mIHRoZXNlIHByb3BvcnRpb25zIGNvbXB1dGVkIGF0IHRoZSB3ZWVrbHkgbGV2ZWwKCmBgYHtyIHJlc3VsdHM9J2hpZGUnfQpwcmVwLnNlc3Npb25zIDwtIHJlYWQuY3N2KCJJbnRlcm1lZGlhdGVfcmVzdWx0cy9yZWd1bGFyaXR5X29mX3N0dWR5L29uX3RvcGljX2FuZF9sYXN0X21pbl9wcm9wb3J0aW9ucy5jc3YiKQojIHN0cihwcmVwLnNlc3Npb25zKQoKbG1lXzFfZGF0IDwtIG1lcmdlKHggPSBwcmVwLnNlc3Npb25zICU+JSBzZWxlY3QoLWVuZHNfd2l0aCgibWFkIikpLCAKICAgICAgICAgICAgICAgICAgIHkgPSBjbHVzdC5hbmQuc2NvcmVzLCAKICAgICAgICAgICAgICAgICAgIGJ5ID0gInVzZXJfaWQiLCBhbGwueCA9IEYsIGFsbC55ID0gVCkKCnN1bW1hcnkobG1lXzFfZGF0KQoKcGxvdC5jb3JyZWxhdGlvbnMobG1lXzFfZGF0KQoKbG1lXzFfZGF0IDwtIGxtZV8xX2RhdCAlPiUgc2VsZWN0KC11c2VyX2lkKQpgYGAKCmBgYHtyfQpzZXQuc2VlZChzZWVkKQpsbWVfMSA8LSBsbWVyKFNDX0ZFX1RPVCB+IG9uX3RvcGljX3Byb3AgKyBvbl90b3BpY19wcm9wX3NkICsgbGFzdF9taW5fcHJvcCArIGxhc3RfbWluX3Byb3Bfc2QgKwogICAgICAgICAgICAgICAgKDF8Y2w0KSwgZGF0YSA9IGxtZV8xX2RhdCwgUkVNTCA9IEZBTFNFKQpzdW1tYXJ5KGxtZV8xKQpgYGAKT25seSAqb25fdG9waWNfcHJvcF9zZCogaXMgc2lnbmlmaWNhbnQ7IGEgdW5pdCBpbmNyZWFzZSwgbGVhZHMgdG8gYSAqZGVjcmVhc2UqIG9mIHRoZSBmaW5hbCBleGFtIHNjb3JlICAKCgpDb21wYXJlIHRoZSBtb2RlbCB3aXRoIHRoZSBiYXNlbGluZQpgYGB7cn0KIyBsbWVfMV9iYXNlIDwtIGxtZXIoU0NfRkVfVE9UIH4gMSArICgxfGNsNCksIGRhdGEgPSBsbWVfMV9kYXQsIFJFTUwgPSBGQUxTRSkKIyBhbm92YShsbWVfMSwgbG1lXzFfYmFzZSkKYGBgCkNhbm5vdCBiZSBjb21wYXJlZCBhcyB0aGV5IGRvIG5vdCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBvYnNlcnZhdGlvbnM6IHNvbWUgb2JzZXJ2YXRpb25zIHdlcmUgcmVtb3ZlZCBmcm9tIHRoZSBsbWVfMSBtb2RlbCBkdWUgdG8gTkEgdmFsdWVzCgpgYGB7cn0KIyMgY29tcHV0ZSBJQ0MKci5zcXVhcmVkR0xNTShsbWVfMSkKYGBgClRoZSBvdmVyYWxsIG1vZGVsIGV4cGxhaW5zIDE4LjY0JSBvZiB2YXJpYWJpbGl0eSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZTsgb25seSBhIHNtYWxsIHBvcnRpb24gLSAzLjg1JSAtIG9mIHRoaXMgdmFyaWFiaWxpdHkgaXMgZXhwbGFpbmVkIGJ5IHRoZSBmaXhlZCBmYWN0b3JzCgoKQ2hlY2tpbmcgaWYgbW9kZWwgYXNzdW1wdGlvbnMgaG9sZApgYGB7ciByZXN1bHRzPSdoaWRlJ30KIyBpZiByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHdpdGggY29uc3RhbnQgc3RhbmRhcmQgZGV2aWF0aW9uCmNoZWNrLnJlc2lkdWFscyhsbWVfMSkKCiMgY2hlY2sgZm9yIG11bHRpY29saW5lYXJpdHkKbWF4KHZpZi5tZXIobG1lXzEpKQpgYGAKQXNzdW1wdGlvbnMgZG8gaG9sZAoKCgojIyMgTW9kZWwgMjogTnVtYmVyIG9mIHN0dWR5IHNlc3Npb25zIHBlciB3ZWVrIGRheSwgYW5kIHdlZWsgZGF5IGVudHJvcHkgb2Ygc3R1ZHkgc2Vzc2lvbiBjb3VudHMgYXMgZml4ZWQgZWZmZWN0cwoKTG9hZGluZyB0aGUgZGF0YQpgYGB7ciByZXN1bHRzPSdoaWRlJ30Kd2Vla2RheS5zZXNzaW9ucyA8LSByZWFkLmNzdigiSW50ZXJtZWRpYXRlX3Jlc3VsdHMvcmVndWxhcml0eV9vZl9zdHVkeS93ZWVrZGF5X3Nlc3Npb25fcHJvcHMuY3N2IikKIyBzdHIod2Vla2RheS5zZXNzaW9ucykKCmxtZV8yX2RhdCA8LSBtZXJnZSh4ID0gd2Vla2RheS5zZXNzaW9ucyAlPiUgc2VsZWN0KDE6OCwgMTEpLAogICAgICAgICAgICAgICAgICB5ID0gY2x1c3QuYW5kLnNjb3JlcywKICAgICAgICAgICAgICAgICAgYnkgPSAidXNlcl9pZCIsIGFsbC54ID0gRkFMU0UsIGFsbC55ID0gVFJVRSkKCmxtZV8yX2RhdCA8LSBsbWVfMl9kYXQgJT4lIHNlbGVjdCgtdXNlcl9pZCkKCiNzdW1tYXJ5KGxtZV8yX2RhdCkKCiMgc2luY2UgdGhlIGNvdW50IHZhcmlhYmxlcyBhcmUgb24gYSB2ZXJ5IGRpZmZlcmVudCBzY2FsZSB0aGFuIHRoZSBlbnRyb3B5LCBzdGFuZGFyZGl6ZSB0aGVtCmxtZV8yX3N0X2RhdCA8LSBzY2FsZS5mZWF0dXJlcyhsbWVfMl9kYXQpCiNzdW1tYXJ5KGxtZV8yX3N0X2RhdCkKYGBgCgpgYGB7cn0Kc2V0LnNlZWQoc2VlZCkKbG1lXzIgPC0gbG1lcihTQ19GRV9UT1QgfiBTdW5fY291bnQgKyBNb25fY291bnQgKyBUdWVfY291bnQgKyBXZWRfY291bnQgKyBUaHVfY291bnQgKyBGcmlfY291bnQgKwogICAgICAgICAgICAgICAgU2F0X2NvdW50ICsgd2Vla2RheV9lbnRyb3B5ICsgKDF8Y2w0KSwgZGF0YSA9IGxtZV8yX3N0X2RhdCwgUkVNTCA9IEZBTFNFKQpzdW1tYXJ5KGxtZV8yKQpgYGAKQXMgaW4gcmVndWxhciBsaW5lYXIgbW9kZWwgKE1vZGVsIDUpLCBNb24sIFR1ZSwgV2VkLCBhbmQgVGh1IHNlc3Npb24gY291bnRzIGFyZSBzaWduaWZpY2FudCwgYXMgaXMgdGhlIHdlZWtkYXkgZW50cm9weS4KCkNvbXBhcmUgdGhlIG1vZGVsIHdpdGggdGhlIGJhc2VsaW5lCmBgYHtyfQpsbWVfMl9iYXNlIDwtIGxtZXIoU0NfRkVfVE9UIH4gMSArICgxfGNsNCksIGRhdGEgPSBsbWVfMl9zdF9kYXQsIFJFTUwgPSBGQUxTRSkKYW5vdmEobG1lXzIsIGxtZV8yX2Jhc2UpCmBgYApNb2RlbCAyIGlzIHNpZ25pZmljYW50bHkgYmV0dGVyIHRoYW4gdGhlIGJhc2VsaW5lLgoKCmBgYHtyfQojIyBjb21wdXRlIElDQwpyLnNxdWFyZWRHTE1NKGxtZV8yKQpgYGAKU2luY2UgbWFyZ2luYWwgUjIgYW5kIGNvbmRpdGlvbmFsIFIyIGFyZSBleGFjdGx5IHRoZSBzYW1lLCBpdCBtZWFucyB0aGF0IGFsbCB0aGUgdmFyaWFiaWxpdHkgaXMgZXhwbGFpbmVkIGJ5IHRoZSBmaXhlZCBmYWN0b3JzOyB0aGUgcmFuZG9tIGZhY3RvciBkb2VzIG5vdCBjb250cmlidXRlIChhbHNvIHZpc2libGUgaW4gdGhlIG1vZGVsIHN1bW1hcnkpLgoKCkNoZWNraW5nIGlmIHJlc2lkdWFscyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aCBjb25zdGFudCBzdGFuZGFyZCBkZXZpYXRpb24KYGBge3IgcmVzdWx0cz0naGlkZSd9CmNoZWNrLnJlc2lkdWFscyhsbWVfMikKY2hlY2sucmVzaWR1YWxzMihsbWVfMikKYGBgCk5vdCBmdWxseSBmaW5lLCBidXQgYWxzbyBub3QgdG9vIGJhZAoKQ2hlY2sgZm9yIG11bHRpY29saW5lYXJpdHkKYGBge3J9Cm1heCh2aWYubWVyKGxtZV8yKSkKYGBgCkl0J3MgT0sKCgojIyMgTW9kZWwgMzogRGFpbHkgcmVzb3VyY2UgdXNlIChhcyBmaXhlZCBlZmZlY3RzKQoKTG9hZGluZyB0aGUgZGF0YS4uLgpgYGB7cn0KcmVzLnVzZS5zdGF0cyA8LSByZWFkLmNzdigiSW50ZXJtZWRpYXRlX3Jlc3VsdHMvcmVndWxhcml0eV9vZl9zdHVkeS9kYWlseV9yZXNvdXJjZV91c2Vfc3RhdGlzdGljc193Mi01XzctMTIuY3N2IikKCmxtZV8zX2RhdCA8LSBtZXJnZShyZXMudXNlLnN0YXRzLCBjbHVzdC5hbmQuc2NvcmVzLCBieSA9ICJ1c2VyX2lkIiwgYWxsLnggPSBGLCBhbGwueSA9IFQpCgpsbWVfM19kYXQgPC0gbG1lXzNfZGF0ICU+JSBzZWxlY3QoLXVzZXJfaWQpCmBgYAoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CiMgRXhhbWluZSBwb3RlbnRpYWwgcHJlZGljdG9ycyAoZml4ZWQgZWZmZWN0cykKc3VtbWFyeShsbWVfM19kYXQpCgpwbG90LmNvcnJlbGF0aW9ucyhsbWVfM19kYXQpCmBgYAoKCiMjIyMgVXNlIHRvdGFsIGRhaWx5IHJlc291cmNlIGNvdW50cyBhcyBmaXhlZCBlZmZlY3RzCmBgYHtyfQpsbWVfMy4xX2RhdCA8LSBsbWVfM19kYXQgJT4lIHNlbGVjdChzdGFydHNfd2l0aCgidG90IiksIGNsNCwgU0NfRkVfVE9UKQoKcGxvdC5jb3JyZWxhdGlvbnMobG1lXzMuMV9kYXQpCmBgYAoKYGBge3J9CnNldC5zZWVkKHNlZWQpCmxtZV8zLjEgPC0gbG1lcihTQ19GRV9UT1QgfiB0b3RfdmlkZW9fY250ICsgdG90X2V4ZV9jbnQgKyB0b3RfbWNxX2NudCArIHRvdF9tY29nX2NudCArIAogICAgICAgICAgICAgICAgICB0b3RfcmVzX2NudCArICgxfGNsNCksIGRhdGEgPSBsbWVfMy4xX2RhdCwgUkVNTCA9IEZBTFNFKQpzdW1tYXJ5KGxtZV8zLjEpCgpgYGAKUHJlZGljdG9ycyB3aXRoIHNpZ2luaWZpY2FuIGVmZmVjdDoKCiogdG90YWwgbnVtYmVyIG9mIGV4ZXJjaXNlLXJlbGF0ZWQgZXZlbnRzIC0gZWFjaCBuZXcgZXZlbnQgb2YgdGhpcyB0eXBlIGRlY3JlYXNlcyB0aGUgZXhhbSBzY29yZSBieSAwLjAwNzMgcG9pbnRzIAoqIHRvdGFsIG51bWJlciBvZiByZWFkaW5nLXJlbGF0ZWQgZXZlbnRzIC0gZWFjaCBuZXcgZXZlbnQgb2YgdGhpcyB0eXBlIGluY3JlYXNlcyB0aGUgZXhhbSBzY29yZSBieSAwLjAwNTEgcG9pbnRzIAoKCkNvbXBhcmUgdGhlIG1vZGVsIHdpdGggdGhlIGJhc2VsaW5lCmBgYHtyfQpsbWVfMy4xX2Jhc2UgPC0gbG1lcihTQ19GRV9UT1QgfiAxICsgKDF8Y2w0KSwgZGF0YSA9IGxtZV8zLjFfZGF0LCBSRU1MID0gRkFMU0UpCmFub3ZhKGxtZV8zLjEsIGxtZV8zLjFfYmFzZSkKYGBgClRoZSBuZXcgbW9kZWwgKGxtZV8zLjEpIGlzIHNpZ25pZmljYW50bHkgYmV0dGVyIHRoYW4gdGhlIGJhc2VsaW5lLgoKCmBgYHtyfQpyLnNxdWFyZWRHTE1NKGxtZV8zLjEpCmBgYApUaGUgb3ZlcmFsbCBtb2RlbCBleHBsYWlucyAyNy44OCUgb2YgdmFyaWFiaWxpdHkgaW4gdGhlIGZpbmFsIGV4YW0gc2NvcmU7IGZpeGVkIGVmZmVjdHMgZXhwbGFpbiBvbmx5IDguMjMlCgoKQ2hlY2tpbmcgaWYgbW9kZWwgYXNzdW1wdGlvbnMgYXJlIHNhdGlzZmllZApgYGB7ciByZXN1bHRzPSdoaWRlJ30KIyBpZiByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGFuZCBpZiBlcXVhbGl0eSBvZiB2YXJpYW5jZSBob2xkcwpjaGVjay5yZXNpZHVhbHMobG1lXzMuMSkKY2hlY2sucmVzaWR1YWxzMihsbWVfMy4xKQoKIyBjaGVjayBmb3IgbXVsdGljb2xpbmVhcml0eQptYXgodmlmLm1lcihsbWVfMy4xKSkKYGBgCkl0IGlzIHF1ZXN0aW9uYWJsZSBpZiB0aGUgZXF1YWxpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbiBob2xkczsgb3RoZXIgdGhpbmdzIGFyZSBmaW5lLgoKCiMjIyMgQWRkIHJlZ3VsYXJpdHkgaW5kaWNhdG9ycyAtIE1BRCBvZiBkYWlseSByZXNvdXJjZSBjb3VudHMgKHRvIGZpeGVkIGVmZmVjdHMpCmBgYHtyfQpsbWVfMy4yX2RhdCA8LSBsbWVfM19kYXQgJT4lIHNlbGVjdChzdGFydHNfd2l0aCgidG90IiksIHN0YXJ0c193aXRoKCJtYWQiKSwgY2w0LCBTQ19GRV9UT1QpCgpwbG90LmNvcnJlbGF0aW9ucyhsbWVfMy4yX2RhdCkKCiMgcmVtb3ZlIG1hZF9yZWNfY250IGFzIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggdG90X3Jlc19jbnQKbG1lXzMuMl9kYXQgPC0gbG1lXzMuMl9kYXQgJT4lIHNlbGVjdCgtbWFkX3Jlc19jbnQpCgojIHN1bW1hcnkobG1lXzMuMl9kYXQpCiMgc29tZSB2YXJpYWJsZXMgaGF2ZSB2ZXJ5IGRpZmZlcmVudCBzY2FsZXMgLSBuZWVkIHRvIGJlIHJlc2NhbGVkIAoKbG1lXzMuMl9zdF9kYXQgPC0gc2NhbGUuZmVhdHVyZXMobG1lXzMuMl9kYXQgJT4lIHNlbGVjdCgtYyhjbDQsIFNDX0ZFX1RPVCkpKQojIHN1bW1hcnkobG1lXzMuMl9zdF9kYXQpCiMgd2hlbiByZXNjYWxsZWQsIGFsbW9zdCBhbGwgcmVndWxhcml0eSBpbmRpY2F0b3JzIChNQUQpIHZhbHVlcyBiZWNvbWUgemVybwpgYGAKTm90IGFwcGxpY2FibGUsIGFzIHdoZW4gcmVzY2FsbGVkLCBNQUQgdmFsdWVzIGJlY29tZSB6ZXJvOyB0aGlzIGlzIGR1ZSB0byB0aGVpciBoaWdobHkgdW5yZWd1bGFyIGRpc3RyaWJ1dGlvbiB3aXRoIG51bWVyb3VzIG91dGxpZXJzCgoKIyMjIE1vZGVsIDQ6IERhaWx5IHRvcGljIGZvY3VzIChhcyBmaXhlZCBlZmZlY3RzKQoKTG9hZGluZyB0aGUgZGF0YS4uLgpgYGB7cn0KdG9waWMuc3RhdHMgPC0gcmVhZC5jc3YoIkludGVybWVkaWF0ZV9yZXN1bHRzL3JlZ3VsYXJpdHlfb2Zfc3R1ZHkvdG9waWNfY291bnRzX3N0YXRpc3RpY3NfdzItNV83LTEyLmNzdiIpCgpsbWVfNF9kYXQgPC0gbWVyZ2UodG9waWMuc3RhdHMsIGNsdXN0LmFuZC5zY29yZXMsIGJ5ID0gInVzZXJfaWQiLCBhbGwueCA9IEYsIGFsbC55ID0gVCkKCmxtZV80X2RhdCA8LSBsbWVfNF9kYXQgJT4lIHNlbGVjdCgtdXNlcl9pZCkKYGBgCgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KIyBFeGFtaW5lIHBvdGVudGlhbCBwcmVkaWN0b3JzIChmaXhlZCBlZmZlY3RzKQoKc3VtbWFyeShsbWVfNF9kYXQpCgpwbG90LmNvcnJlbGF0aW9ucyhsbWVfNF9kYXQpCmBgYAoKCiMjIyMgVXNlIHRoZSBwcm9wb3J0aW9uIG9mIGRheXMgd2l0aCBlYWNoIHRvcGljIGZvY3VzIGFzIHRoZSBmaXhlZCBlZmZlY3RzCgpOb3RlOiBpbml0aWFsbHksIEkgd2FudGVkIHRvIHVzZSBkYXlzICh3aXRoIGVhY2ggdG9waWMgZm9jdXMpLCBidXQgWF9kYXlzIHZhcmlhYmxlcyBhcmUgaGlnaGx5IG11dHVhbGx5IGNvcnJlbGF0ZWQKCmBgYHtyfQpsbWVfNC4xX2RhdCA8LSBsbWVfNF9kYXQgJT4lIHNlbGVjdChlbmRzX3dpdGgoInByb3AiKSwgY2w0LCBTQ19GRV9UT1QpCgpwbG90LmNvcnJlbGF0aW9ucyhsbWVfNC4xX2RhdCkKCiMgcmVtb3ZlIG9yaWVudF9wcm9wIGFzIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggbWV0YWNvZ19wcm9wOyBhbHNvIHByal9wcm9wIGFzIGhhdmluZyB6ZXJvIGNvcnJlbGF0aW9uIHdpdGggdGhlIGV4YW0gc2NvcmUKbG1lXzQuMV9kYXQgPC0gbG1lXzQuMV9kYXQgJT4lIHNlbGVjdCgtYyhwcmpfcHJvcCwgb3JpZW50X3Byb3ApKQpgYGAKCmBgYHtyfQpzZXQuc2VlZChzZWVkKQpsbWVfNC4xIDwtIGxtZXIoU0NfRkVfVE9UIH4gb250b3BpY19wcm9wICsgcmV2aXNpdF9wcm9wICsgbWV0YWNvZ19wcm9wICsgKDF8Y2w0KSwgCiAgICAgICAgICAgICAgICBkYXRhID0gbG1lXzQuMV9kYXQsIFJFTUwgPSBGQUxTRSkKc3VtbWFyeShsbWVfNC4xKQoKYGBgClRoZSBvbmx5IHNpZ25pZmljYW50IGZpeGVkIGVmZmVjdCBpcyAqb250b3BpY19wcm9wKiAtIHRoZSBwcm9wb3J0aW9uIG9mIGFjdGl2ZSBkYXlzIHdoZW4gYSBzdHVkZW50IHdhcyBwcmVwYXJpbmcgZm9yIHRoZSB3ZWVrJ3MgbGVjdHVyZQoKCmBgYHtyfQpyLnNxdWFyZWRHTE1NKGxtZV80LjEpCmBgYApUaGUgb3ZlcmFsbCBtb2RlbCBleHBsYWlucyAyMi43JSBvZiB2YXJpYW5jZSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZTsgZml4ZWQgZWZmZWN0cyBjb250cmlidXRlIG9ubHkgMiUgb2YgZXhwbGFpbmVkIHZhcmlhbmNlCgoKQ29tcGFyZSB0aGUgbW9kZWwgd2l0aCB0aGUgYmFzZWxpbmUKYGBge3J9CmxtZV80LjFfYmFzZSA8LSBsbWVyKFNDX0ZFX1RPVCB+IDEgKyAoMXxjbDQpLCBkYXRhID0gbG1lXzQuMV9kYXQsIFJFTUwgPSBGQUxTRSkKYW5vdmEobG1lXzQuMSwgbG1lXzQuMV9iYXNlKQpgYGAKVGhlIG5ldyBtb2RlbCAobG1lXzQuMSkgaXMgc2lnbmlmaWNhbnRseSBiZXR0ZXIgdGhhbiB0aGUgYmFzZWxpbmUuCgoKIyMjIyBVc2UgdGhlIHRvdGFsIG51bWJlciBvZiBhY3Rpb25zIHBlciBkYXkgd2l0aCBwYXJ0aWN1bGFyIHRvcGljIGZvY3VzIGFzIHRoZSBmaXhlZCBlZmZlY3RzCgpgYGB7cn0KbG1lXzQuMl9kYXQgPC0gbG1lXzRfZGF0ICU+JSBzZWxlY3Qoc3RhcnRzX3dpdGgoInRvdCIpLCBjbDQsIFNDX0ZFX1RPVCkKCnBsb3QuY29ycmVsYXRpb25zKGxtZV80LjJfZGF0KQoKIyByZW1vdmUgdG90X21ldGFjb2dfY250IGFzIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggc2V2ZXJhbCBvdGhlciB2YXJpYWJsZXM7IGFsc28sIHRvdF9yZXZpc2l0X2NudCBoYXMgemVybyBjb3JyZWxhdGlvbiB3aXRoIHRoZSBmaW5hbCBleGFtIHNjb3JlCmxtZV80LjJfZGF0IDwtIGxtZV80LjJfZGF0ICU+JSBzZWxlY3QoLWModG90X21ldGFjb2dfY250LCB0b3RfcmV2aXNpdF9jbnQpKQpgYGAKCmBgYHtyfQpzZXQuc2VlZChzZWVkKQpsbWVfNC4yIDwtIGxtZXIoU0NfRkVfVE9UIH4gdG90X29udG9waWNfY250ICsgdG90X29yaWVudF9jbnQgKyB0b3RfcHJqX2NudCArICgxfGNsNCksIAogICAgICAgICAgICAgICAgZGF0YSA9IGxtZV80LjJfZGF0LCBSRU1MID0gRkFMU0UpCnN1bW1hcnkobG1lXzQuMikKCmBgYAoKYGBge3J9CnIuc3F1YXJlZEdMTU0obG1lXzQuMikKYGBgCgpWZXJ5IHBvb3IgbW9kZWwuLi4KCgojIyMjIENvc2lkZXIgdXNpbmcgaW5kaWNhdG9ycyBvZiByZWd1bGFyaXR5IG9mIHRvcGljIGZvY3VzIGFzIHRoZSBmaXhlZCBlZmZlY3RzCgpgYGB7cn0KbG1lXzQuM19kYXQgPC0gbG1lXzRfZGF0ICU+JSBzZWxlY3Qoc3RhcnRzX3dpdGgoIm1hZCIpLCBjbDQsIFNDX0ZFX1RPVCkKCnBsb3QuY29ycmVsYXRpb25zKGxtZV80LjNfZGF0KQpgYGAKCkJldHRlciBub3QgdG8sIHNpbmNlIHRoZSBtYWRfWF9jbnQgdmFyaWFibGVzIGhhdmUgdmVyeSBsb3cgY29ycmVsYXRpb24gd2l0aCB0aGUgZmluYWwgZXhhbSBzY29yZSAtIHNpZ25pZmljYW50IGZpeGVkIGVmZmVjdCBjYW5ub3QgYmUgZXhwZWN0ZWQuCgoKIyMjIE1vZGVsIDU6IFdlZWtseSByZXNvdXJjZSB1c2UgaW5kaWNhdG9ycyBhcyBmaXhlZCBlZmZlY3RzCgpJbmRpY2F0b3JzIGFyZSBjb21wdXRlZCBhdCB0aGUgd2VlayBsZXZlbCwgYmFzZWQgb24gdGhlIGZvbGxvd2luZyBwcmluY2lwbGU6IGEgc2NvcmUgb2Ygb25lIGlzIGdpdmVuIHRvIGEgc3R1ZGVudCAoZm9yIGEgZ2l2ZW4gd2VlayksIGlmIGhlL3NoZSB1c2VkIGNlcnRhaW4ga2luZCBvZiByZXNvdXJjZSAoZS5nLiB2aWRlbykgbW9yZSB0aGFuIHRoZSBhdmVyYWdlIChtZWRpYW4pIHVzZSBvZiB0aGUgdGhhdCByZXNvdXJjZSB0eXBlIGluIHRoZSBnaXZlbiB3ZWVrCgpMb2FkaW5nIHRoZSBkYXRhCmBgYHtyIHJlc3VsdHM9J2hpZGUnfQpyZXMudXNlLmluZCA8LSByZWFkLmNzdigiSW50ZXJtZWRpYXRlX3Jlc3VsdHMvcmVndWxhcml0eV9vZl9zdHVkeS9yZXNfdXNlX2luZGljYXRvcnNfdzItMTMuY3N2IikKc3RyKHJlcy51c2UuaW5kKQoKbG1lXzVfZGF0IDwtIG1lcmdlKHggPSByZXMudXNlLmluZCwgeSA9IGNsdXN0LmFuZC5zY29yZXMsCiAgICAgICAgICAgICAgICAgIGJ5ID0gInVzZXJfaWQiLCBhbGwueCA9IEZBTFNFLCBhbGwueSA9IFRSVUUpCgpsbWVfNV9kYXQgPC0gbG1lXzVfZGF0ICU+JSBzZWxlY3QoLXVzZXJfaWQpCgpzdW1tYXJ5KGxtZV81X2RhdCkKCnBsb3QuY29ycmVsYXRpb25zKGxtZV81X2RhdCkKCiMgcmVzX2luZCBhbmQgTUNRX2luZCBhcmUgaGlnaGx5IGNvcnJlbGF0ZWQsIHJlbW92ZSBvbmUgb2YgdGhlbQpsbWVfNV9kYXQgPC0gbG1lXzVfZGF0ICU+JSBzZWxlY3QoLVZJREVPX2luZCkKYGBgCgpgYGB7cn0Kc2V0LnNlZWQoc2VlZCkKbG1lXzUgPC0gbG1lcihTQ19GRV9UT1QgfiBNQ1FfaW5kICsgRVhFX2luZCArIFJFU19pbmQgKyBNRVRBQ09HX2luZCArICgxfGNsNCksIAogICAgICAgICAgICAgICAgZGF0YSA9IGxtZV81X2RhdCwgUkVNTCA9IEZBTFNFKQpzdW1tYXJ5KGxtZV81KQoKYGBgClByZWRpY3RvcnMgd2l0aCBzaWduaWZpY2FudCBlZmZlY3Q6CgoqIE1DUV9pbmQgLSBhIHVuaXQgaW5jcmVhc2Ugb2YgdGhpcyBpbmRpY2F0b3IgKGllLCBvbmUgd2VlayBtb3JlIHdoZW4gYSBzdHVkZW50J3MgdXNlIG9mIE1DUXMgaXMgaGlnaGVyIHRoYW4gdGhlIGF2ZXJhZ2UgKG1lZGlhbikgdXNlIG9mIE1DUSBpbiB0aGF0IHdlZWspLCBpbmNyZWFzZXMgdGhlIGZpbmFsIGV4YW0gc2NvcmUgYnkgMC43Nzg2IHBvaW50cyAKKiBFWEVfaW5kIC0gYSB1bml0IGluY3JlYXNlIG9mIHRoaXMgaW5kaWNhdG9yIChpZSwgb25lIHdlZWsgbW9yZSB3aGVuIGEgc3R1ZGVudCdzIHVzZSBvZiBleGVyY2lzZXMgaXMgaGlnaGVyIHRoYW4gdGhlIGF2ZXJhZ2UgKG1lZGlhbikgdXNlIG9mIGV4ZXJjaXNlcyBpbiB0aGF0IHdlZWspLCAqZGVjcmVhc2VzKiB0aGUgZXhhbSBzY29yZSBieSAwLjk3NjcgcG9pbnRzCiogUkVTX2luZCAtIGEgdW5pdCBpbmNyZWFzZSBvZiB0aGlzIGluZGljYXRvciAoaWUsIG9uZSB3ZWVrIG1vcmUgd2hlbiBhIHN0dWRlbnQncyB1c2Ugb2YgcmVhZGluZyBtYXRlcmlhcyBpcyBoaWdoZXIgdGhhbiB0aGUgYXZlcmFnZSAobWVkaWFuKSB1c2Ugb2YgcmVhZGluZyBjb250ZW50IGluIHRoYXQgd2VlayksIGluY3JlYXNlcyB0aGUgZXhhbSBzY29yZSBieSAwLjM1NSBwb2ludHMuCgpDb21wYXJlIHRoZSBtb2RlbCB3aXRoIHRoZSBiYXNlbGluZQpgYGB7cn0KbG1lXzVfYmFzZSA8LSBsbWVyKFNDX0ZFX1RPVCB+IDEgKyAoMXxjbDQpLCBkYXRhID0gbG1lXzVfZGF0LCBSRU1MID0gRkFMU0UpCmFub3ZhKGxtZV81LCBsbWVfNV9iYXNlKQpgYGAKVGhlIG1vZGVsIGlzIHNpZ25pZmljYW50bHkgYmV0dGVyIHRoYW4gdGhlIGJhc2VsaW5lLgoKCmBgYHtyfQpyLnNxdWFyZWRHTE1NKGxtZV81KQpgYGAKVGhlIGJlc3QgbW9kZWwgc28gZmFyOiBpdCBleHBsYWlucyAyOS4yNCUgb2YgdGhlIHZhcmlhYmlsaXR5IGluIHRoZSBmaW5hbCBleGFtIHNjb3JlOyBvdXQgb2YgdGhhdCwgMTguMzUlIGFyZSBleHBsYWluZWQgYnkgdGhlIGZpeGVkIGZhY3RvcnMuIAoKQ2hlY2tpbmcgaWYgbW9kZWwgYXNzdW1wdGlvbnMgYXJlIHNhdGlzZmllZApgYGB7ciByZXN1bHRzPSdoaWRlJ30KIyBpZiByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGFuZCBpZiBlcXVhbGl0eSBvZiB2YXJpYW5jZSBob2xkcwpjaGVjay5yZXNpZHVhbHMobG1lXzUpCmNoZWNrLnJlc2lkdWFsczIobG1lXzUpCgojIGNoZWNrIGZvciBtdWx0aWNvbGluZWFyaXR5Cm1heCh2aWYubWVyKGxtZV81KSkKYGBgCkl0IGNhbiBiZSBzYWlkIHRoYXQgdGhlIGFzc3VtcHRpb25zIGhvbGQKCgojIyMgTW9kZWwgNjogVG9waWMgZm9jdXMgaW5kaWNhdG9ycyBhcyBmaXhlZCBlZmZlY3RzCgpJbmRpY2F0b3JzIGFyZSBjb21wdXRlZCBhdCB0aGUgd2VlayBsZXZlbCwgYmFzZWQgb24gdGhlIGZvbGxvd2luZyBwcmluY2lwbGU6CmEgc2NvcmUgb2Ygb25lIGlzIGdpdmVuIHRvIGEgc3R1ZGVudCAoZm9yIGEgZ2l2ZW4gd2VlayksIGlmIGhpcy9oZXIgbnVtYmVyIG9mIGV2ZW50cyByZWxhdGVkIHRvIGEgcGFydGljdWxhciB0b3BpYyB0eXBlIChlLmcuIHJldmlzaXRpbmcpIHdhcyBhYm92ZSB0aGUgYXZlcmFnZSAobWVkaWFuKSBudW1iZXIgb2YgZXZlbnRzIHdpdGggdGhhdCB0b3BpYyB0eXBlIGluIHRoZSBnaXZlbiB3ZWVrCgpXZWVrcyA2IGFuZCAxMyBhcmUgZXhjbHVkZWQgZnJvbSB0aGVzZSBjb21wdXRhdGlvbnMsIGFzIGR1cmluZyB0aGVzZSB3ZWVrcyBvbmUgY2FuIGV4cGVjdCAgZGlmZmVyZW50IGJlaGF2aW9yYWwgcGF0dGVybnMgdGhhbiB1c3VhbC4KCkxvYWRpbmcgdGhlIGRhdGEKYGBge3IgcmVzdWx0cz0naGlkZSd9CnRvcGljLmluZCA8LSByZWFkLmNzdigiSW50ZXJtZWRpYXRlX3Jlc3VsdHMvcmVndWxhcml0eV9vZl9zdHVkeS90b3BpY19iYXNlZF9pbmRpY2F0b3JzX3cyLTVfNy0xMi5jc3YiKQpzdHIodG9waWMuaW5kKQoKbG1lXzZfZGF0IDwtIG1lcmdlKHggPSB0b3BpYy5pbmQsIHkgPSBjbHVzdC5hbmQuc2NvcmVzLAogICAgICAgICAgICAgICAgICBieSA9ICJ1c2VyX2lkIiwgYWxsLnggPSBGQUxTRSwgYWxsLnkgPSBUUlVFKQoKbG1lXzZfZGF0IDwtIGxtZV82X2RhdCAlPiUgc2VsZWN0KC11c2VyX2lkKQoKc3VtbWFyeShsbWVfNl9kYXQpCgpwbG90LmNvcnJlbGF0aW9ucyhsbWVfNl9kYXQpCgojIG9yaWVudF9pbmQgYW5kIG1ldGFjb2dfaW5kIGFyZSBoaWdobHkgY29ycmVsYXRlZCwgcmVtb3ZlIG9uZSBvZiB0aGVtCmxtZV82X2RhdCA8LSBsbWVfNl9kYXQgJT4lIHNlbGVjdCgtb3JpZW50X2luZCkKYGBgCgpgYGB7cn0Kc2V0LnNlZWQoc2VlZCkKbG1lXzYgPC0gbG1lcihTQ19GRV9UT1QgfiBvbnRvcGljX2luZCArIHJldmlzaXRfaW5kICsgbWV0YWNvZ19pbmQgKyBwcmpfaW5kICsgKDF8Y2w0KSwgCiAgICAgICAgICAgICAgICBkYXRhID0gbG1lXzZfZGF0LCBSRU1MID0gRkFMU0UpCnN1bW1hcnkobG1lXzYpCmBgYApTaWduaWZpY2FudCBmaXhlZCBlZmZlY3RzOgoKKiBvbnRvcGljX2luZCAtIGEgdW5pdCBpbmNyZWFzZSBpbiB0aGlzIGluZGljYXRvciAoaWUsIG9uZSB3ZWVrIG1vcmUgd2hlbiBhIHN0dWRlbnQncyBudW1iZXIgb2YgZXZlbnRzIHdpdGggJ29udG9waWMnIGZvY3VzIGlzIGhpZ2hlciB0aGFuIHRoZSBhdmVyYWdlIChtZWRpYW4pIG51bWJlciBvZiBldmVudHMgd2l0aCB0aGF0IGZvY3VzIGluIHRoYXQgd2VlayksIGluY3JlYXNlcyB0aGUgZmluYWwgZXhhbSBzY29yZSBieSAwLjUxODUgcG9pbnRzIAoqIHJldmlzaXRfaW5kIC0gYSB1bml0IGluY3JlYXNlIGluIHRoaXMgaW5kaWNhdG9yIChpZSwgb25lIHdlZWsgbW9yZSB3aGVuIGEgc3R1ZGVudCdzIG51bWJlciBvZiBldmVudHMgd2l0aCAncmV2aXNpdG5nJyBmb2N1cyBpcyBoaWdoZXIgdGhhbiB0aGUgYXZlcmFnZSAobWVkaWFuKSBudW1iZXIgb2YgZXZlbnRzIHdpdGggdGhhdCBmb2N1cyBpbiB0aGF0IHdlZWspLCAqZGVjcmVhc2VzKiB0aGUgZmluYWwgZXhhbSBzY29yZSBieSAwLjQ0MjYgcG9pbnRzCgpDb21wYXJlIHRoZSBtb2RlbCB3aXRoIHRoZSBiYXNlbGluZQpgYGB7cn0KbG1lXzZfYmFzZSA8LSBsbWVyKFNDX0ZFX1RPVCB+IDEgKyAoMXxjbDQpLCBkYXRhID0gbG1lXzZfZGF0LCBSRU1MID0gRkFMU0UpCmFub3ZhKGxtZV82LCBsbWVfNl9iYXNlKQpgYGAKVGhlIG1vZGVsIGlzIHNpZ25pZmljYW50bHkgYmV0dGVyIHRoYW4gdGhlIGJhc2VsaW5lLgoKYGBge3J9CnIuc3F1YXJlZEdMTU0obG1lXzYpCmBgYApUaGUgbW9kZWwgZXhwbGFpbnMgMTkuNDIlIG9mIHRoZSB2YXJpYWJpbGl0eSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZTsgb3V0IG9mIHRoYXQsIDQuMTglIGFyZSBleHBsYWluZWQgYnkgdGhlIGZpeGVkIGZhY3RvcnMuIAoKQ2hlY2tpbmcgaWYgbW9kZWwgYXNzdW1wdGlvbnMgYXJlIHNhdGlzZmllZApgYGB7ciByZXN1bHRzPSdoaWRlJ30KIyBpZiByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGFuZCBpZiBlcXVhbGl0eSBvZiB2YXJpYW5jZSBob2xkcwpjaGVjay5yZXNpZHVhbHMobG1lXzYpCiNjaGVjay5yZXNpZHVhbHMyKGxtZV82KQoKIyBjaGVjayBmb3IgbXVsdGljb2xpbmVhcml0eQptYXgodmlmLm1lcihsbWVfNikpCmBgYApJdCdzIGZpbmUgLSB0aGUgYXNzdW1wdGlvbnMgaG9sZC4KCgojIyMgTW9kZWwgNzogVGltZSBnYXAgKGluIGRheXMpIGJldHdlZW4gdHdvIGNvbnNlY3V0aXZlIGFjdGl2ZSBkYXlzIChhcyBmaXhlZCBlZmZlY3QpCgpMb2FkaW5nIHRoZSBkYXRhCmBgYHtyIHJlc3VsdHM9J2hpZGUnfQpyZWcuaW5kIDwtIHJlYWQuY3N2KCJJbnRlcm1lZGlhdGVfcmVzdWx0cy9yZWd1bGFyaXR5X29mX3N0dWR5L2dhcHNfYmV0d2Vlbl9jb25zZWN1dGl2ZV9sb2dpbnNfdzItMTMuY3N2IikKc3RyKHJlZy5pbmQpCgpsbWVfN19kYXQgPC0gbWVyZ2UoeCA9IHJlZy5pbmQgJT4lIHNlbGVjdCh1c2VyX2lkLCBtZWRpYW5fZ2FwKSwgeSA9IGNsdXN0LmFuZC5zY29yZXMsCiAgICAgICAgICAgICAgICAgIGJ5ID0gInVzZXJfaWQiLCBhbGwueCA9IEZBTFNFLCBhbGwueSA9IFRSVUUpCgpsbWVfN19kYXQgPC0gbG1lXzdfZGF0ICU+JSBzZWxlY3QoLXVzZXJfaWQpCgpzdW1tYXJ5KGxtZV83X2RhdCkKCnBsb3QuY29ycmVsYXRpb25zKGxtZV83X2RhdCkKYGBgCgpgYGB7cn0Kc2V0LnNlZWQoc2VlZCkKbG1lXzcgPC0gbG1lcihTQ19GRV9UT1QgfiBtZWRpYW5fZ2FwICsgKDF8Y2w0KSwgCiAgICAgICAgICAgICAgICBkYXRhID0gbG1lXzdfZGF0LCBSRU1MID0gRkFMU0UpCnN1bW1hcnkobG1lXzcpCmBgYApNZWRpYW4gZ2FwLCBtZWFzdXJlZCBpbiBkYXlzLCBpcyBzaWduaWZpY2FudDogb25lIHVuaXQgKGRheSkgaW5jcmVhc2UgaW4gdGhpcyBwcmVkaWN0b3IgbGVhZHMgdG8gYSAxLjAxIGRlY3Jhc2UgaW4gdGhlIHN0dWRlbnQncyBmaW5hbCBleGFtIHNjb3JlLgoKYGBge3J9CnIuc3F1YXJlZEdMTU0obG1lXzcpCmBgYApUaGUgbW9kZWwgZXhwbGFpbnMgMTUuMTElIG9mIHRoZSB2YXJpYWJpbGl0eSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZTsgb3V0IG9mIHRoYXQsIG9ubHkgMi41JSBhcmUgZXhwbGFpbmVkIGJ5IHRoZSBmaXhlZCBmYWN0b3JzLiAKCkNoZWNraW5nIGlmIG1vZGVsIGFzc3VtcHRpb25zIGFyZSBzYXRpc2ZpZWQKYGBge3IgcmVzdWx0cz0naGlkZSd9CiMgaWYgcmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgaWYgZXF1YWxpdHkgb2YgdmFyaWFuY2UgaG9sZHMKY2hlY2sucmVzaWR1YWxzKGxtZV83KQojY2hlY2sucmVzaWR1YWxzMihsbWVfNikKCiMgY2hlY2sgZm9yIG11bHRpY29saW5lYXJpdHkKbWF4KHZpZi5tZXIobG1lXzcpKQpgYGAKSXQncyBmaW5lIC0gdGhlIGFzc3VtcHRpb25zIGhvbGQuCgo=